嗨大家好,我是Eric!今天我們來談談一個超好用的 Web API,intersection Observer,它是一種只在用戶實際看到或需要內容時才開始加載該內容的技術。
假設我們有 10萬張圖片要一次一起加載,我想…這會是一場災難,用戶體驗會非常差!
那麼我們就來看看怎麼實現這個 API 吧~
我們會有多個皮卡丘當做默認圖片,這樣可以加到瀏覽器緩存,而真實的圖片則加到自定義的 data-src裡面
<div class="card-list">
<div class="item">
<img src="./img/pikajiu.webp" alt="" data-src="https://picsum.photos/id/670/600/400" />
</div>
<!-- 以下為更多的 item ... -- >
</div>
接著我們要監聽圖片是否和視口有交叉,有交叉代表user看到這張圖片,這時候我們就載入這張圖片
// 創建 IntersectionObserver
const ob = new IntersectionObserver(
(entries)=>{
console.log('IntersectionObserver 與視口交叉了');
console.log(entries);
console.log('IntersectionObserver 與視口交叉了');
for(entries of entries){
if(entries.isIntersecting){
const img = entries.target; // 取得被觀察的 img
img.src = img.dataset.src; // 將 data-src暫存的圖片賦值到已交叉的圖片中
}
}
}, {
// root: null, // 設定為 null 代表使用瀏覽器的 viewport
// rootMargin: 0, // 設定為 0 代表不加入任何邊界
threshold: 0 // 設定為 0 代表碰到邊框就觸發
})
const img = document.querySelectorAll('img[data-src]');
img.forEach((item)=>{
ob.observe(item);
});
在 IntersectionObserver 的回調函式中,我們接收到一個名為 entries 的參數,這是一個包含多個 IntersectionObserverEntry 物件的陣列,且每個 IntersectionObserverEntry 物件都有一些重要的屬性,其中兩個很重要:
isIntersecting:這個布林值表示目標元素(在我們的例子中是圖片)是否與視口交叉。如果是 true,那意味著用戶可以看到這個元素,我們應該開始加載它。
target:這個屬性則是當前被觀察的目標元素,也就是我們希望實現 Lazy Loading 的圖片。
透過這兩個屬性,我們能夠準確地知道哪些圖片應該被加載,從而實現更高效的 Lazy Loading。
結論:
IntersectionObserver 不僅可以提高網頁的性能,還可以顯著提升 User 體驗,尤其是在移動端上更是如此,這麼好用的 API 趕快在你的專案上用起來吧~ 這次的分享就到這邊,我們下次見~